import * as THREE from "three"
import { TourTransitionDirection, TourTransitionType } from "../enum/tourTransition.enum"
import Vectors from "../three/Vectors"
import { isPanOrMesh } from "../utils/viewmode.util"
import TourTransitionFactory from "./TourTransitionFactory"

export default class TourPanTransitionLegacy {
  settingsData: any
  cameraPose: any
  rotate: any
  stopRotating: any
  getCurve: any
  type: number
  toIndex: number
  currentTransitionPromise: any
  onStopRequested: () => Promise<void>
  constructor(e, t, i, s, n) {
    ;(this.settingsData = e),
      (this.cameraPose = t),
      (this.rotate = i),
      (this.stopRotating = s),
      (this.getCurve = n),
      (this.type = TourTransitionType.Burns),
      (this.toIndex = -1),
      (this.currentTransitionPromise = null),
      (this.onStopRequested = () => Promise.resolve())
  }
  get active() {
    return null !== this.currentTransitionPromise
  }
  get promise() {
    return this.currentTransitionPromise ? this.currentTransitionPromise : Promise.resolve()
  }
  async stop() {
    this.currentTransitionPromise && (await this.onStopRequested(), await this.promise, (this.currentTransitionPromise = null))
  }
  start(e) {
    if (this.active) throw Error("Transition already active")
    const { deferred: t } = this.build(e.path, e.snapshot, e.nextSnapshot, e.panOverrides)
    return (
      (this.currentTransitionPromise = t.then(() => {
        this.currentTransitionPromise = null
      })),
      this
    )
  }
  build(e, t, i, s) {
    this.onStopRequested = async () => {
      await this.stopRotating()
    }
    const { panDirection: n, panAngle: r } = s,
      a = TourTransitionFactory.getPanValues(this.settingsData, !1, n, r),
      h = a.direction
    let l = a.radiansPerMs
    if (void 0 !== h && h !== TourTransitionDirection.Auto) l *= h
    else if (e) {
      const t = this.cameraPose.position.clone().setY(0),
        i = e.map(e => e.position),
        s = this.getCurve(i).curve.getPointAt(0.1).setY(0).clone().sub(t).normalize(),
        n = Vectors.FORWARD.clone().applyQuaternion(this.cameraPose.rotation),
        r = Math.sign(n.cross(s).y)
      l = 0 !== r ? l * r : l
    } else if (i && t) {
      if ((!isPanOrMesh(t.metadata.cameraMode) && (l = -l), t.metadata.scanId === i.metadata.scanId)) {
        const e = Vectors.FORWARD.clone().applyQuaternion(this.cameraPose.rotation),
          t = Vectors.FORWARD.clone().applyQuaternion(i.metadata.cameraQuaternion),
          s = Math.sign(e.cross(t).y)
        l = 0 !== s ? l * s : l
      }
    }
    return { deferred: this.rotate(a.ms, new THREE.Vector2(l, 0)) }
  }
}
